package com.beta.resource.utils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.beta.resource.model.Metal;
import com.beta.resource.protocol.Mecha;
import com.beta.resource.services.UserEnvService;

@Component
@ServerEndpoint("/wss/mecha/{suid}")
public class WebSocket {
    public static final String LISTENER_URL = "/wss/mecha/";
    private static Map<String, Mecha> gSessionPool = new HashMap<>();
    private static UserEnvService mEnvService;
    private Logger log = LoggerFactory.getLogger(getClass());

    public static void setEnvService(UserEnvService service) {
        mEnvService = service;
    }

    @OnOpen
    public synchronized void onOpen(Session session, @PathParam(value = "suid") String suid) {
        log.debug("new client connected:"+ suid);
        Mecha mecha = new Mecha(suid);
        mecha.setSession(session);
        mecha.setEnvService(mEnvService);
        gSessionPool.putIfAbsent(session.getId(), mecha);
    }

    @OnClose
    public synchronized void onClose(Session session) {
        log.debug(session.getId() + " closed");
        gSessionPool.remove(session.getId());
    }

    @OnMessage
    public void onMessage(Session session, String msg) {
        log.debug("recv mesg:" + msg);
        Mecha mecha = gSessionPool.get(session.getId());
        if (mecha != null) {
            Metal metal = mecha.doRespond(msg);
            try {
                mecha.send(metal);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        log.debug("ret:" + (mecha == null?false:true));

    }

    @OnError
    public synchronized void onError(Session session, Throwable error) {
        error.printStackTrace();
        try {
            session.close();
            gSessionPool.remove(session.getId());
        } catch (IOException e) {
            e.printStackTrace();
            gSessionPool.remove(session.getId());
        }
    }

    public synchronized void sendBroadcast(String mesg) {
        for (Mecha mecha : gSessionPool.values()) {
            mecha.send(mesg);
        }
    }
}
